#include "Tracer.h"
#include "SDBus.h"

using namespace libemb;
int SDBusConnection::openUser(bool dflt)
{
	if (m_bus!=NULL)
	{
		return RC_OK;
	}	
	int rc;
	if (dflt)
	{
		rc = sd_bus_default_user(&m_bus);
	}
	else
	{
		rc = sd_bus_open_user(&m_bus);
	}
	if (rc>=0)
	{
		return RC_OK;
	}
	TRACE_ERR_CLASS("open user bus error: %s\n",ERRMSG(-rc));
	m_bus = NULL;
	return RC_ERROR;
}

int SDBusConnection::openSystem(bool dflt)
{
	if (m_bus!=NULL)
	{
		return RC_OK;
	}
	
	int rc;
	if (dflt)
	{
		rc = sd_bus_default_system(&m_bus);
	}
	else
	{
		rc = sd_bus_open_system(&m_bus);
	}
	if (rc>=0)
	{
		return RC_OK;
	}
	TRACE_ERR_CLASS("open system bus error: %s\n",ERRMSG(-rc));
	m_bus = NULL;
	return RC_ERROR;
}

SDBus* SDBusConnection::getBus()
{
	return m_bus;
}

void SDBusConnection::close()
{
	sd_bus_slot_unref(m_slot);
	sd_bus_flush_close_unref(m_bus);
}

/* 设置消息回调 */
int SDBusConnection::bindObjectVTable(std::string path, std::string interface, SDBusVTable* vtable)
{
	int rc = sd_bus_add_object_vtable(m_bus,
                             &m_slot,
                             CSTR(path),  /* object path */
                             CSTR(interface),   /* interface name */
                             vtable,
                             NULL);/* userdata=NULL */
	if (rc < 0) 
	{
		TRACE_REL_CLASS("bind object vtable error: %s\n", ERRMSG(-rc));
	    return RC_ERROR;
	}
	return RC_OK;
}

int SDBusConnection::requestName(std::string name)
{
	//int rc = sd_bus_request_name_async(m_bus, NULL, CSTR(name), 0, NULL, NULL);
	int rc = sd_bus_request_name(m_bus,CSTR(name),SD_BUS_NAME_REPLACE_EXISTING);
	if (rc<0)
	{
		TRACE_REL_CLASS("request name error: %s\n", ERRMSG(-rc));
		return RC_ERROR;
	}
	m_name = name;
	return  RC_OK;
}

int SDBusConnection::releaseName(std::string name)
{
	int rc = sd_bus_release_name(m_bus,CSTR(name));
	if (rc<0)
	{
		TRACE_REL_CLASS("release name error: %s\n", ERRMSG(-rc));
		return RC_ERROR;
	}
	m_name = "";
	return  RC_OK;
}

std::string SDBusConnection::getName()
{
	return m_name;
}
std::string SDBusConnection::getUniqueName()
{
	const char *unique = NULL;
	int rc = sd_bus_get_unique_name(m_bus, &unique);
	if (rc<0)
	{
		return std::string("");
	}
	return  std::string(unique);
}

bool SDBusConnection::process(int usTimeout)
{
    int rc = sd_bus_process(m_bus, NULL);
    if (rc < 0) 
	{
        TRACE_ERR_CLASS("Failed to process bus: %s\n", ERRMSG(-rc));
        return false;
    }
    if (rc > 0) /* 处理完了当前请求,继续处理下一个请求 */
    {
    	return true;
    }
    /* 当sd_bus_process返回0时(没有任何请求),必须调用sd_bus_wait一次 */
    rc = sd_bus_wait(m_bus, (uint64)usTimeout);
    if (rc < 0) 
	{
        TRACE_ERR_CLASS("Failed to wait on bus: %s\n", ERRMSG(-rc));
        return false;
    }
	return true;
}









